package org.fuys.coder.domain.config.service;

import com.baomidou.mybatisplus.annotation.TableField;
import org.fuys.coder.domain.config.model.req.AppConfigAddVersionReq;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.common.config.app
 * @className: BaseConfig
 * @author: WangJing
 * @description: 基础配置类 用于进行动态配置修改
 * @date: 2024/8/30 12:21
 * @version: 1.0
 */
@Component
public abstract class BaseConfig {
    @TableField(exist = false)
    //标注此成员不是表字段
    private final ReentrantLock lock=new ReentrantLock();

    protected Integer version;

    protected String description;
    //todo 子类更新值时存在浅拷贝风险



    public void setConfigValue(String key,Object value,Integer version){
        if (lock.isLocked()) {
            return;
        }
        lock.lock();
        Field field=null;
        try{
            field = this.getFieldByName(this.getClass(),key);
            if(field==null){
                throw new IllegalArgumentException("配置类中不存在此配置项");
            }
            field.setAccessible(true);
            final Class<?> type = field.getType();
            final Object trueValue = convertToWrapper(value.toString(), type);
            field.set(this,trueValue);
            setConfigDBValue(this,version);
        }catch (Exception e){
            throw new IllegalArgumentException("不合法的配置");
        }
        finally {
            if(field!=null) {
                field.setAccessible(false);
            }
            lock.unlock();
        }
    }

    public void switchSubConfigVersion(Integer version){
        this.switchConfigVersion(version);
    }

    public void addSubConfigVersion(AppConfigAddVersionReq req){
        this.addConfigVersion(req);
    }

    public List<? extends BaseConfig> selectSubConfig(){
        return this.getConfigList();
    }

    //转换类型 因为配置中可能有其他类型
    protected Object convertToWrapper(String value, Class<?> primitiveType) {
        if (primitiveType == Integer.class) {
            return Integer.valueOf(value);
        } else if (primitiveType == Double.class) {
            return Double.valueOf(value);
        }else if(primitiveType==String.class){
            return value;
        }
        // 其他类型可以添加到这里...
        throw new IllegalArgumentException("不支持的数据类型: " + primitiveType);
    }

    protected Field getFieldByName(Class<?> clazz,String name){
        try {
            return clazz.getDeclaredField(name);
        } catch (NoSuchFieldException e) {
            return null;
        }
    }


    /**
     * @param instance: 更改数据实例
     * @param version: 版本号
     * @return void
     * @author WangJing
     * @description 子类实现 同步数据库中数据
     * @date 2024/9/1 20:04
     */
    protected abstract void setConfigDBValue(Object instance,Integer version) throws RuntimeException;

    /**
     * @param version: 版本号信息
     * @return void
     * @author WangJing
     * @description 切换配置至其他版本号
     * @date 2024/9/1 20:07
     */
    protected abstract void switchConfigVersion(Integer version);

    /**
     * @param req: 携带各类配置所需数据
     * @return void
     * @author WangJing
     * @description 添加新版本版本配置信息
     * @date 2024/9/1 20:28
     */
    protected abstract void addConfigVersion(AppConfigAddVersionReq req);

    /**
     * @param :
     * @return List<BaseConfig>
     * @author WangJing
     * @description 获取此类型配置全部可用信息
     * @date 2024/9/1 20:29
     */
    protected abstract  List<? extends BaseConfig> getConfigList();

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
